<template>
  <div>
    <el-row v-for="row in rowSize" :key="row" class="condition-row" type="flex" justify="end">
      <el-col :span="span" v-for="(item, i) in fieldList.slice((row - 1) * columns, row * columns)" :key="i">
        <div class="condition-item" :style="{ marginRight: i === columns - 1 ? '0px' : '16px' }">
          <span class="condition-item-label"
                :style="{ width: lengthUnit(item.labelWidth) || lengthUnit(computedLabelWidth), textAlign: labelAlign }">{{
              item.label
            }}</span>
          <el-input class="condition-item-input" v-if="item.type == 'input'" :placeholder="item.placeholder"
                    v-model="conditionData[item.field]" :clearable="item.clearable">
          </el-input>
          <el-date-picker class="condition-item-input" v-if="item.type == 'timeRange'"
                          v-model="conditionData[item.field]"
                          :type="item.timePickerRangeType || 'datetimerange'" value-format="timestamp"
                          :range-separator="item.rangeSeparator || '至'"
                          :start-placeholder="item.startPlaceholder || '开始日期'"
                          :end-placeholder="item.endPlaceholder || '结束日期'"
                          @change="(val) => handleDateTimeRangeChange(val, item.field, item.timePickerRangeType)">
          </el-date-picker>

          <el-date-picker class="condition-item-input" v-if="item.type == 'time'" v-model="conditionData[item.field]"
                          :type="item.timePickerRangeType || 'datetime'" value-format="timestamp">
          </el-date-picker>

          <el-select class="condition-item-input" v-if="item.type === 'select'" v-model="conditionData[item.field]"
                     :placeholder="item.placeholder || ''" :clearable="item.clearable" :filterable="item.filterable"
                     :multiple="item.multiple">
            <el-option v-for="(option, i) in selectOptions[item.field]" :key="i"
                       :label="option[item.optionItemTitleField || 'name']"
                       :value="option[item.optionItemValueField || 'value']">
            </el-option>
          </el-select>

          <template v-if="item.type === 'numberRange'">
            <el-input-number :placeholder="item.startPlaceholder" v-model="conditionData[item.field][0]"
                             controls-position="right"/>
            <span style="margin: 0px 4px;">{{ item.rangeSeparator || '至' }}</span>
            <el-input-number :placeholder="item.endPlaceholder" v-model="conditionData[item.field][1]"
                             controls-position="right"/>
          </template>

          <slot v-if="item.type === 'template'" :name="item.field" :data="conditionData"></slot>
        </div>
      </el-col>
      <el-col class="btn-container-left" v-if="fieldList.length % columns !== 0 && row === rowSize" :span="span">
        <el-button type="primary" @click="submitForm">{{ searchText }}</el-button>
        <el-button style="margin-left: 8px" @click="resetForm">{{ resetText }}</el-button>
      </el-col>
    </el-row>
    <el-row class="condition-row" v-if="fieldList.length % columns === 0">
      <el-col class="btn-container-right" :span="8" :offset="16">
        <el-button type="primary" @click="submitForm">{{ searchText }}</el-button>
        <el-button style="margin-left: 8px" @click="resetForm">{{ resetText }}</el-button>
      </el-col>
    </el-row>
  </div>
</template>

<script>
import _ from "lodash";
import {lengthUnit} from '../../utils';

export default {
  name: 'QueryCondition',
  props: {
    columns: {
      type: Number,
      default: function () {
        return 3;
      }
    },

    fieldList: {
      type: Array,
      default: function () {
        return [];
      }
    },

    enterCommitPath: {
      type: String,
      default: undefined
    },

    searchText: {
      type: String,
      default: '搜索'
    },

    resetText: {
      type: String,
      default: '重置'
    },

    labelWidth: {
      type: [String, Number],
      default: 'auto'
    },

    labelAlign: {
      type: String,
      default: 'right'
    }
  },

  data() {
    return {
      lengthUnit,
      conditionData: {},
      selectOptions: {}
    };
  },

  watch: {
    fieldList: {
      deep: true,
      handler(newVal) {
        this.conditionData = this.initConditionData(newVal);
        this.initSelectOptions();
      }
    }
  },

  computed: {
    rowSize() {
      return Math.ceil(this.fieldList.length / this.columns);
    },

    span() {
      return parseInt(24 / this.columns);
    },
    computedLabelWidth() {
      let res = this.labelWidth;
      if (res === 'auto') {
        let width = 0;
        this.fieldList.forEach(item => {
          let labelWidth = item.label.length * 14;
          width = _.max([width, labelWidth]);
        });
        res = width;
      }
      return res;
    }
  },


  created() {
    this.conditionData = this.initConditionData(this.fieldList);
    this.initSelectOptions();
  },

  mounted() {
    if (this.enterCommitPath) {
      document.addEventListener('keyup', this.enterKey);
    }
  },

  destroyed() {
    if (this.enterCommitPath) {
      document.removeEventListener('keyup', this.enterKey);
    }
  },

  methods: {
    initConditionData(filters) {
      let filterData = {};
      if (filters) {
        filters.forEach(async (item) => {
          if (item.field) {
            filterData[item.field] = item.defaultValue || undefined;
            if (item.type === 'select') {
              this.selectOptions[item.field] = item.options || [];
            } else if (item.type === 'numberRange' || item.type === 'timeRange') {
              filterData[item.field] = item.defaultValue ? item.defaultValue : [];
            }
          }
        });
      }
      return filterData;
    },

    getFilterData() {
      return this.conditionData;
    },

    submitForm() {
      this.$emit('onSearch', this.conditionData);
      this.$emit('on-search', this.conditionData);
    },

    resetForm() {
      Object.keys(this.conditionData).forEach((key) => {
        if (this.conditionData[key] instanceof Array) {
          this.conditionData[key] = [];
        } else {
          this.conditionData[key] = undefined;
        }
      });
      if (this.$listeners['onReset'] || this.$listeners['on-reset']) {
        this.$emit('onReset');
        this.$emit('on-reset');
      } else {
        this.submitForm();
      }
    },

    initSelectOptions() {
      if (this.fieldList) {
        this.fieldList.forEach(async item => {
          if (item.type === 'select') {
            let options = item.options || [];
            if (item.optionApi && typeof (item.optionApi) == 'function') {
              let data = await item.optionApi(item.queryParams);
              let remoteResponsePath = item.remoteResponsePath || ['data', 'rows'];
              remoteResponsePath.forEach(path => {
                data = data[path];
              });
              options = data;
            }
            this.selectOptions[item.field] = options;
            this.$forceUpdate();
          }
        });
      }
    },

    handleDateTimeRangeChange(val, fieldName, type) {
      if (val instanceof Array) {
        let start = parseInt(val[0]);
        let end = parseInt(val[1]);
        if (type === 'daterange') {
          end += (24 * 60 * 60 * 1000 - 1000);
        }
        this.conditionData[fieldName] = [start, end];
      }
    },

    enterKey(event) {
      const componentName = this.$options.name;
      const {name, path} = this.$route;
      if (componentName === 'QueryCondition' && (name === this.enterCommitPath || path === this.enterCommitPath)) {
        const code = event.keyCode;
        if (code == 13) {
          this.submitForm();
        }
      }
    },
  }
};
</script>

<style lang="less" scoped>
.condition-row {
  margin-top: 16px;

  .condition-item {
    display: flex;
    align-items: center;
    margin-right: 16px;

    .condition-item-label {
      display: inline-block;
      white-space: nowrap;
      margin-right: 8px;
      font-size: 14px;
      font-weight: 400;
      color: #666666;
      text-align: right;
    }

    .condition-item-input {
      flex: 1;
    }
  }

  .btn-container-right {
    text-align: right;
  }

  .btn-container-left {
    text-align: left;
  }
}

:first-child {
  margin-top: 0px;
}
/deep/ .el-input__inner {
  height: 36px;
}
</style>
